/*
 * Created on 29.11.2003
 */
package de.javakicker;

import java.awt.Point;
import java.io.IOException;
import java.io.Writer;
import java.util.*;

import de.javakicker.GameEngine.RuntimePlayerImpl;

/**
 * The Class XmlGameRecorder.
 *
 * @author Till Krullmann
 */

public class XmlGameRecorder implements GameRecorder
{
	
	/** Der Ausgabestrom f�r die Aufzeichnung. */ 
	XmlWriter writer;

	/** The minute count. */
	int minuteCount = 0;
	
	/** The move count. */
	int moveCount = 0;
	
	/** The minute open. */
	boolean minuteOpen = false;

/**
 * Constructor. Schreibt die ersten Informationen (XML-Version, Encoding) und oeffnet das match-Tag.
 *
 * @param w Writer der fuer den XmlWriter benutzt wird.
 * @throws IOException Signals that an I/O exception has occurred.
 */
	public XmlGameRecorder(Writer w)
		throws IOException
	{
		this.writer = new XmlWriter(w, true);

		writer.writeStartDocument();
		writer.writeStartElement("match");
		writer.writeAttributeString("version", "js"); // fuer das Frontend-Team - so wissen sie, dass die XML von uns kommt
	}

/**
 * Schreibt die Positionsangabe (x,y) in den aktuellen Tag.
 *
 * @param pos Position als Point.
 * @throws IOException Signals that an I/O exception has occurred.
 */
	private void writePositionAttributes(Point pos)
		throws IOException
	{
		writer.writeAttributeString("x", Integer.toString(GameEngine.FIELD_HEIGHT - 1 - pos.y));
		writer.writeAttributeString("y", Integer.toString(pos.x));
	}
	
	/**
	 * Write ball position attributes.
	 *
	 * @param pos the pos
	 * @throws IOException Signals that an I/O exception has occurred.
	 */
	private void writeBallPositionAttributes(Point pos)
			throws IOException
		{
			writer.writeAttributeString("bx", Integer.toString(GameEngine.FIELD_HEIGHT - 1 - pos.y));
			writer.writeAttributeString("by", Integer.toString(pos.x));
		}
	
	/**
	 * Write player position attributes.
	 *
	 * @param id the id
	 * @param pos the pos
	 * @throws IOException Signals that an I/O exception has occurred.
	 */
	private void writePlayerPositionAttributes(String id, Point pos)
			throws IOException
		{
			writer.writeAttributeString("opid", id);
			writer.writeAttributeString("opx", Integer.toString(GameEngine.FIELD_HEIGHT - 1 - pos.y));
			writer.writeAttributeString("opy", Integer.toString(pos.x));
		}
	
	/* 
	 * @see javakicker.de.GameRecorder#writeTeams(javakicker.de.Team[], java.util.Collection)
	 */
	public void writeTeams(Team[] teams, Collection<RuntimePlayerImpl> players, String[] jerseys) 
			throws IOException
	{
		for (int i = 0; i < 2; i++)
		{
			writer.writeStartElement("team");
			writer.writeAttributeString("id", Integer.toString(i+1));
			writer.writeAttributeString("name", teams[i].getName());
			writer.writeAttributeString("jersey", (jerseys[i] != null) ? jerseys[i] : "RED");  // Trikot

			for (Object obj : players) {
				RuntimePlayerImpl player = (RuntimePlayerImpl) obj;
				if(player.getTeam().getName().equalsIgnoreCase(teams[i].getName())) {		//prueft, ob es sich um das aktuelle Team handelt
					writer.writeStartElement("player");
					writer.writeAttributeString("id", player.getJavaKickerId());
					writer.writeAttributeString("name", player.getPlayerName());
					writer.writeAttributeString("no", player.getPlayerNo());
					writer.writeEndElement();
				}
			}			
			writer.writeEndElement();
		}
	}


	/* 
	 * @see javakicker.de.GameRecorder#writeResetPositions(java.util.Collection)
	 */
	public void writeResetPositions(Collection<RuntimePlayerImpl> players)
		throws IOException
	{
		writer.writeStartElement("reset");

		Iterator<RuntimePlayerImpl> i = players.iterator();
		while (i.hasNext())
		{
			RuntimePlayer rtPlayer = (RuntimePlayer) i.next();

			writer.writeStartElement("player");
			writer.writeAttributeString("id", rtPlayer.getJavaKickerId());
			Point pos = new Point(-1,-1);
			
			if (rtPlayer.getFouls()==3) rtPlayer.setPosition(pos);
			writePositionAttributes(rtPlayer.getPosition());
			
			// direction beim reset mit eintragen (IDs von 1-10)
			if(Integer.parseInt(rtPlayer.getJavaKickerId()) < 5) writer.writeAttributeString("direction", "right");
			else if(Integer.parseInt(rtPlayer.getJavaKickerId()) >= 5) writer.writeAttributeString("direction", "left");
			
			writer.writeEndElement();
		}

		writer.writeEndElement();
	}


	/* 
	 * @see javakicker.de.GameRecorder#nextMinute()
	 */
	public void nextMinute()
		throws IOException
	{
		if (minuteOpen)
			writer.writeEndElement();

		writer.writeStartElement("minute");
		writer.writeAttributeString("count", Integer.toString(++minuteCount));
		
		moveCount = 0;
		
		minuteOpen = true;
	}

	/* 
	 * @see javakicker.de.GameRecorder#writeAction(javakicker.de.GameEngine.RuntimePlayerImpl, java.lang.String, java.awt.Point, int, java.lang.String)
	 */
	public void writeAction(RuntimePlayerImpl player, String action, Point pushedPlayerTarget, int direction, String pushedPlayerId, int goal, boolean foul)
		throws IOException
	{
		if (!minuteOpen)
			throw new IllegalStateException();
		
		writer.writeStartElement("action");
		writer.writeAttributeString("id", player.getJavaKickerId());
		writePositionAttributes(player.getPosition());
		
		if(pushedPlayerId != null) {
			writePlayerPositionAttributes(pushedPlayerId, pushedPlayerTarget);
		}
		else if(pushedPlayerTarget != null){
			writeBallPositionAttributes(pushedPlayerTarget);
		}
		
		switch(direction) {
			case Player.UP:
				writer.writeAttributeString("direction", "right");
				break;
			case Player.DOWN:
				writer.writeAttributeString("direction", "left");
				break;
			case Player.LEFT:
				writer.writeAttributeString("direction", "up");
				break;
			case Player.RIGHT:
				writer.writeAttributeString("direction", "down");
				break;
			default: break;
		}
		
		writer.writeAttributeString("action", action);
		writer.writeAttributeString("goal", String.valueOf(goal));
		writer.writeAttributeString("goals", player.getGoals());
		writer.writeAttributeString("foul", foul ? "1" : "0");
		writer.writeAttributeString("cards", String.valueOf(player.getFouls()));
		writer.writeAttributeString("touches", player.getTouches());
		String comment = player.getComment();
		if(comment != null) writer.writeAttributeString("comment", comment);
		writer.writeEndElement();
	}

	/* 
	 * @see javakicker.de.GameRecorder#writeComment(java.lang.String)
	 */
	public void writeComment(String text)
		throws IOException
	{
		writer.writeComment(text);
	}


	/*
	 * @see javakicker.de.GameRecorder#close()
	 */
	public void close()
		throws IOException
	{
		writer.writeEndDocument();
		writer.flush();
		writer.close();
	}
	
}